#include "main_window.h"
#include "ui_main_window.h"

#include <iostream>
#include <QTextCodec>

MainWindow::MainWindow(QWidget *parent)
    : QMainWindow(parent), ui(new Ui::MainWindowClass)
{
    ui->setupUi(this);

    // setting up mainArea
    _mainarea = new MainArea();
    _mainarea->setGeometry(0,0,975,650);
    ui->scroll->setWidget(_mainarea);

    _curPageIndex = 0;

    cursor = new QAction(QIcon(":/icons/cursor.png"), tr("&Cursor mode"), (QObject*)this);
    cursor->setStatusTip("Cursor mode");
    cursor->setCheckable(true);
    cursor->setChecked(true);
    connect(cursor, SIGNAL(triggered()), SLOT(cursorSlot()));

    addText = new QAction(QIcon(":/icons/add_text.png"), tr("&Add text object"), (QObject*)this);
    addText->setStatusTip("Add text object");
    addText->setCheckable(true);
    connect(addText, SIGNAL(triggered()), SLOT(textSlot()));

    addImg = new QAction(QIcon(":/icons/add_img.png"), tr("&Add image object"), (QObject*)this);
    addImg->setStatusTip("Add image object");
    addImg->setCheckable(true);
    connect(addImg, SIGNAL(triggered()), SLOT(imageSlot()));

    addFile = new QAction(QIcon(":/icons/save.png"), tr("&Add file reference object"), (QObject*)this);
    addFile->setStatusTip("Add file reference object");
    addFile->setCheckable(true);
    connect(addFile, SIGNAL(triggered()), SLOT(fileSlot()));

    addPin = new QAction(QIcon(":/icons/pin.png"), tr("&Add Pinoteo object"), (QObject*)this);
    addPin->setStatusTip("Add Pinoteo object");
    addPin->setCheckable(true);
    connect(addPin, SIGNAL(triggered()), SLOT(pinSlot()));

    addLine = new QAction(QIcon(":/icons/line.png"), tr("&Add line"), (QObject*)this);
    addLine->setStatusTip("Add line");
    addLine->setCheckable(true);
    connect(addLine, SIGNAL(triggered()), SLOT(lineSlot()));

    delLine = new QAction(QIcon(":/icons/line_del.png"), tr("&Remove line"), (QObject*)this);
    delLine->setStatusTip("Remove line");
    delLine->setCheckable(true);
    connect(delLine, SIGNAL(triggered()), SLOT(line_del_Slot()));

    grid = new QAction(QIcon(":/icons/grid.png"), tr("&Grid mode on/off"), (QObject*)this);
    grid->setStatusTip("Grid mode on/off");
    grid->setCheckable(true);
    connect(grid, SIGNAL(triggered()), SLOT(gridSlot()));

    font = new QAction(QIcon(":/icons/font.png"), tr("&Font settings"), (QObject*)this);
    font->setStatusTip("Font settings");
    font->setCheckable(false);
    connect(font, SIGNAL(triggered()), SLOT(fontSlot()));

    color = new QAction(QIcon(":/icons/color.png"), tr("&Color settings"), (QObject*)this);
    color->setStatusTip("Color settings");
    color->setCheckable(false);
    connect(color, SIGNAL(triggered()), SLOT(colorSlot()));

    zoom_in = new QAction(QIcon(":/icons/zoom_in.png"), tr("&Zoom in"), (QObject*)this);
    zoom_in->setStatusTip("Zoom in");
    zoom_in->setCheckable(false);
    connect(zoom_in, SIGNAL(triggered()), SLOT(zoominSlot()));

    zoom_out = new QAction(QIcon(":/icons/zoom_out.png"), tr("&Zoom out"), (QObject*)this);
    zoom_out->setStatusTip("Zoom out");
    zoom_out->setCheckable(false);
    connect(zoom_out, SIGNAL(triggered()), SLOT(zoomoutSlot()));

    nextd = new QAction(QIcon(":/icons/next.png"), tr("&Go to next Pinoteo page"), (QObject*)this);
    nextd->setStatusTip("Go to next Pinoteo page");
    nextd->setCheckable(false);
    connect(nextd, SIGNAL(triggered()), SLOT(nextSlot()));

    prevd = new QAction(QIcon(":/icons/prev.png"), tr("&Go to previous Pinoteo page"), (QObject*)this);
    prevd->setStatusTip("Go to previous Pinoteo page");
    prevd->setCheckable(false);
    connect(prevd, SIGNAL(triggered()), SLOT(prevSlot()));

    ui->toolBar->addAction(cursor);
    ui->toolBar->addAction(addText);
    ui->toolBar->addAction(addImg);
    ui->toolBar->addAction(addFile);
    ui->toolBar->addAction(addPin);
    ui->toolBar->addAction(addLine);
    ui->toolBar->addAction(delLine);
    ui->toolBar->addAction(grid);
    ui->toolBar->addAction(font);
    ui->toolBar->addAction(color);
    ui->toolBar->addAction(zoom_in);
    ui->toolBar->addAction(zoom_out);
    ui->toolBar->addAction(prevd);
    ui->toolBar->addAction(nextd);

    _mainarea->nextAction = CURSOR;

    if (QCoreApplication::arguments().count() > 1)
    {
    	_filename = QCoreApplication::arguments().at(1);
        Open(false, true);
    }
    else
    	_filename = "";
    setTitle(_filename);

}

MainWindow::~MainWindow()
{
    delete ui;
}

void MainWindow::resizeEvent(QResizeEvent *)
{
    ui->scroll->setGeometry(QRect(0, 0, width(),
                                height() - ui->toolBar->height() - ui->statusBar->height() - ui->menuBar->height()));
}

//Save data from file
bool MainWindow::Save()
{
    // if there is no filename - ask it
    if (_filename == "")
    {
    	_filename = QFileDialog::getSaveFileName(NULL, "Save...", 0, tr("Pinoteo Save Files (*.pin)"));
    }
    if (!_filename.endsWith(".pin"))
    	_filename += ".pin";
    QFile datafile(_filename);
    datafile.open(QIODevice::WriteOnly);
    datafile.write(_mainarea->Store());
    datafile.close();
    setTitle(_filename);
    return true;
}

bool MainWindow::Open(QString filename)
{
    _mainarea->deleteAreas();

    QFile datafile(filename);
    datafile.open(QIODevice::ReadOnly);

    QByteArray test = datafile.readAll();
    datafile.close();
    SmartByteArray data(test);
    _mainarea->parse_data(data);
    _mainarea->selectAll();
    _filename = filename;
    setTitle(filename);
    return true;
}

// Read data from file
bool MainWindow::Open(bool from_buffer, bool from_start_file)
{

	_pages.clear();

    QByteArray test;
    if(from_buffer)
    {
        test = _mainarea->restore_from_buffer();
    }
    else
    {
        if (!from_start_file)
        	_filename = QFileDialog::getOpenFileName(NULL, "Open...", 0, tr("Pinoteo Save Files (*.pin)"));

        QFile datafile(_filename);
        datafile.open(QIODevice::ReadOnly);

        test = datafile.readAll();
        datafile.close();
        _pages.append(_filename);
    }

    SmartByteArray data(test);
    _mainarea->parse_data(data);
    _mainarea->selectAll();
    return true;
}

bool MainWindow::parse_data(const SmartByteArray &data)
{
    QList<QByteArray> s_data = data.split("</object>\n", 10);

    for(int i=0; i<s_data.count(); i++)
    {
        SmartByteArray temp_(s_data[i]);
        QList<QByteArray> temp_s_ = temp_.split(">",1,1);
        QString params_str = temp_s_[0];
        QByteArray data = temp_s_[1];
        QStringList params = params_str.split(" ");

        QString type = params[1].split("=")[1];

        //line is an unusual object - it doesnt have any geometry
        if (type=="line")
        {
            int src_s = params[2].split("=")[1].toInt();
            int dest_s = params[3].split("=")[1].toInt();
            Area *src, *dest;
            src = _mainarea->get_area_by_serial(src_s);
            dest = _mainarea->get_area_by_serial(dest_s);
            _mainarea->addLine(src, dest);
            continue;
        }

        //geometry
        int x = params[2].split("=")[1].toInt();
        int y = params[3].split("=")[1].toInt();
        int w = params[4].split("=")[1].toInt();
        int h = params[5].split("=")[1].toInt();
        // colors
        int r = params[6].split("=")[1].toInt();
        int g = params[7].split("=")[1].toInt();
        int b = params[8].split("=")[1].toInt();
        //serial
        int serial = params[9].split("=")[1].toInt();
        //check types

        if(type == "image")
        {
            _mainarea->addImage(x, y, w, h, serial, data, false);
            _mainarea->get_area_by_serial(serial)->setColor(QColor(r,g,b,255));
        }
        else if (type == "text")
        {
            QString data_ = QString::fromUtf8(data);
            _mainarea->addText(x, y, w, h, serial, data_);
            _mainarea->get_area_by_serial(serial)->setColor(QColor(r,g,b,255));
        }
        else if (type == "file")
        {
            _mainarea->addFile(x, y, w, h, serial, QString::fromUtf8(data.left(data.length()-1)));
            _mainarea->get_area_by_serial(serial)->setColor(QColor(r,g,b,255));
        }
        
    }


    //setTitle(filename);

    return true;
}

void MainWindow::on_actionTerminate_triggered()
{
    close();
}

void MainWindow::on_actionSave_triggered()
{
    Save();
}

void MainWindow::on_actionOpen_triggered()
{
   if (!_mainarea->ask4confirm())
       return;
   _mainarea->deleteAreas();
   Open();
}

void MainWindow::on_actionSelect_all_triggered()
{
    _mainarea->selectAll();
}

void MainWindow::cursorSlot()
{
    deselectToolbarTools();
    cursor->setChecked(true);
    _mainarea->nextAction = CURSOR;
}

void MainWindow::textSlot()
{
    deselectToolbarTools();
    addText->setChecked(true);
    _mainarea->nextAction = TEXT;
}

void MainWindow::imageSlot()
{
    deselectToolbarTools();
    addImg->setChecked(true);
    _mainarea->nextAction = IMG;
}

void MainWindow::fileSlot()
{
    deselectToolbarTools();
    addFile->setChecked(true);
    _mainarea->nextAction = LINK;
}

void MainWindow::pinSlot()
{
    deselectToolbarTools();
    addPin->setChecked(true);
    _mainarea->nextAction = PIN;
}

void MainWindow::lineSlot()
{
    deselectToolbarTools();
    cursor->setChecked(true);
    _mainarea->nextAction = CURSOR;
    _mainarea->addLine();
}

void MainWindow::line_del_Slot()
{
    deselectToolbarTools();
    cursor->setChecked(true);
    _mainarea->nextAction = CURSOR;
    _mainarea->delLine();
}

void MainWindow::gridSlot()
{
    if (_mainarea->grid_mode)
        _mainarea->grid_mode = false;
    else
        _mainarea->grid_mode = true;
    _mainarea->areas_to_grid();
}

void MainWindow::fontSlot()
{
    _mainarea->set_font_for_areas();
}

void MainWindow::zoominSlot()
{
    _mainarea->zoom_in();
}

void MainWindow::zoomoutSlot()
{
    _mainarea->zoom_out();
}

void MainWindow::nextSlot()
{
    if (_curPageIndex > _pages.count()-2)
        return;
    _curPageIndex ++;
    Open(_pages[_curPageIndex]);

}

void MainWindow::prevSlot()
{
    if (_curPageIndex < 1)
        return;
    _curPageIndex --;
    Open(_pages[_curPageIndex]);
    //_curPageIndex = 0;

}

void MainWindow::colorSlot()
{
    _mainarea->set_color_for_areas();
}

void MainWindow::deselectToolbarTools()
{
    cursor->setChecked(false);
    addText->setChecked(false);
    addImg->setChecked(false);
    addFile->setChecked(false);
    addPin->setChecked(false);
    addLine->setChecked(false);
    delLine->setChecked(false);
}

void MainWindow::on_actionDelete_triggered()
{
    _mainarea->deleteSelectedAreas();
}

void MainWindow::on_actionPrint_triggered()
{
    _mainarea->printPreview();
}

void MainWindow::on_actionNew_triggered()
{
    if (!_mainarea->ask4confirm())
       return;
    _mainarea->deleteAreas();
    _filename = "";
    setTitle("Untilted");
}

void MainWindow::on_actionVersion_triggered()
{
    QMessageBox::information(this, "About::Version", QString("Pinoteo version ")+QString(VERSION)+
                             "\n\nDeveloping team: \n Vasily Matveev\n Anastacia Ponomareva\n\n"+
                             "http://www.pinoteo.com");
}

void MainWindow::closeEvent(QCloseEvent *e)
{
    if (_mainarea->ask4confirm())
        e->accept();
    else e->ignore();
}

void MainWindow::setTitle(const QString &title)
{
    setWindowTitle("Pinoteo :: "+title);
}

void MainWindow::on_actionSave_as_triggered()
{
    QString filename = QFileDialog::getSaveFileName(NULL, "Save...", "", "*.pin");
    if (filename != "")
    {
    	_filename = filename;
        Save();
    }
}

void MainWindow::on_actionUndo_triggered()
{
    Open(true);
}

void MainWindow::on_actionCut_triggered()
{
    on_actionCopy_triggered();
    _mainarea->deleteSelectedAreas();
}

void MainWindow::on_actionCopy_triggered()
{
    _exchangeBuffer = _mainarea->store_selected();
}

void MainWindow::on_actionPaste_triggered()
{
    _mainarea->restore_from_ex_buffer(_exchangeBuffer);
}

void MainWindow::on_actionCheck_for_updates_triggered()
{
    QDesktopServices::openUrl(QUrl("http://www.pinoteo.com/update"));
}

void MainWindow::on_actionAdd_triggered()
{
    // adding a page to the page list
    QString filename = QFileDialog::getOpenFileName(NULL, "Open...", 0, tr("Pinoteo Save Files (*.pin)"));
    if (filename == "")
        Open(filename);
    _pages.append(filename);
}
